function [accessPaths, aerPlotPaths, dopplerPlotPaths, latencyPlotPaths] = Satellite(tleFile, groundStations, outputDir, satelliteIndex, startTime, stopTime,reviewable)
% Satellite - 仅进行后台计算，不显示任何动画或图形界面
% 输入：
%   tleFile         - 字符串，TLE文件路径
%   groundStations  - Cell数组，每个元素是包含以下字段的结构体：
%                     latitude, longitude, minElevationAngle, name
%   outputDir       - 字符串，输出目录路径
%   satelliteIndex  - 正整数，要仿真的卫星索引（从1开始）
%   startTime       - datetime，仿真开始时间
%   stopTime        - datetime，仿真结束时间
%
% 输出：
%   accessPaths     - 接入报告路径列表
%   aerPlotPaths    - AER 图像路径列表
%   dopplerPlotPaths- 多普勒图像路径列表
%   latencyPlotPaths- 时延图像路径列表

accessPaths = {};
aerPlotPaths = {};
dopplerPlotPaths = {};
latencyPlotPaths = {};

% 设置仿真时间
parts = split(strtrim(startTime), ',');
nums = str2double(parts);
y = nums(1);
m = nums(2);
d = nums(3);
h = nums(4);
mi = nums(5);
s = nums(6);
startTime = datetime(y, m, d, h, mi, s);
parts = split(strtrim(stopTime), ',');
nums = str2double(parts);
y = nums(1);
m = nums(2);
d = nums(3);
h = nums(4);
mi = nums(5);
s = nums(6);
stopTime = datetime(y, m, d, h, mi, s);
sampleTime = 30; % seconds
% 创建仿真场景
sc = satelliteScenario(startTime, stopTime, sampleTime);

% 导入星历数据
sat = satellite(sc, tleFile);
numSatellites = length(sat);
% 动态划分三组索引
groupSize = ceil(numSatellites / 3);  % 每组最大数量（前两组可能比第三组少）
idxGroup1 = 1 : groupSize;
idxGroup2 = (groupSize + 1) : min(2 * groupSize, numSatellites);
idxGroup3 = (2 * groupSize + 1) : numSatellites;




targetSat = sat(satelliteIndex);
sensorName = sprintf('Satellite %d Camera', satelliteIndex);
cam = conicalSensor(targetSat, ...
    'Name', sensorName, ...
    'MaxViewAngle', reviewable); % 可以改为参数传入，如 inputArgs.dopplerFreq

% 创建多个地面站
gsList = {};
% 接入报告目录
accessReportFolder = fullfile(outputDir, 'access_reports');
if ~exist(accessReportFolder, 'dir')
    mkdir(accessReportFolder);
end

% AER 图像目录
aerPlotFolder = fullfile(outputDir, 'aer_plots');
if ~exist(aerPlotFolder, 'dir')
    mkdir(aerPlotFolder);
end

% 多普勒频移图像目录
dopplerPlotFolder = fullfile(outputDir, 'doppler_plots');
if ~exist(dopplerPlotFolder, 'dir')
    mkdir(dopplerPlotFolder);
end

% 时延图像目录
latencyPlotFolder = fullfile(outputDir, 'latency_plots');
if ~exist(latencyPlotFolder, 'dir')
    mkdir(latencyPlotFolder);
end

% 处理每个地面站
for i = 1:length(groundStations)
    gsStruct = groundStations{i};
    gs = groundStation(sc, ...
        gsStruct.latitude, ...
        gsStruct.longitude, ...
        'MinElevationAngle', gsStruct.minElevationAngle, ...
        'Name', gsStruct.name);
    gs.MarkerColor = 'red';
    gs.ShowLabel = true;
    gs.LabelFontSize = 11;
    gsList{end+1} = gs;

    % 创建接入关系
    accessObj = access(gs, sat);
    set(accessObj, LineWidth="1");
    set(accessObj(idxGroup1), LineColor="#FF6929");
    set(accessObj(idxGroup2), LineColor="#139FFF");
    set(accessObj(idxGroup3), LineColor="#64D413");

    % 生成变量名并保存接入报告
    baseName = gsStruct.name;
    intervals = accessIntervals(accessObj);
    if height(intervals) > 0
        intervalsSorted = sortrows(intervals, "StartTime", "ascend");
        fileNameCSV = fullfile(accessReportFolder, ['access_report_', baseName, '.csv']);
        writetable(intervalsSorted, fileNameCSV, 'WriteRowNames', false);
        accessPaths{end+1} = fileNameCSV;
    else
    end

    % AER 报告
    timeVector = startTime:seconds(sampleTime):stopTime;
    [azimuth,elevation,range] = aer(sat(satelliteIndex),gs);
    aer_table = table(timeVector', azimuth', elevation', range', ...
        'VariableNames', {'Time', 'Azimuth', 'Elevation', 'Range'});
    aerPlotPath = plotAER(aer_table, baseName, sat(satelliteIndex).ID, aerPlotFolder);
    aerPlotPaths{end+1} = aerPlotPath;

    % 计算时延
    [~, ~, latencyPlotPath] = cal_latency(sat(satelliteIndex), gs, 30, 2, latencyPlotFolder);
    latencyPlotPaths{end+1} = latencyPlotPath;

    % 计算多普勒频移
    [~, ~, ~, dopplerPlotPath] = cal_doppler(sat(satelliteIndex), gs, 5e9, 2, dopplerPlotFolder);
    dopplerPlotPaths{end+1} = dopplerPlotPath;
end

% 不再显示地面站地图
% figure; geoscatter(...); geolimits(...); title(...);

% 不再打开卫星场景视图
% v = satelliteScenarioViewer(sc,"ShowDetails",false); show(sat.Orbit); play(sc);

end